﻿using Caliburn.Micro;
using SD.Infrastructure.DTOBase;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.Infrastructure.WPF.Extensions;
using SD.Infrastructure.WPF.Models;
using SD.IOC.Core.Mediators;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SlamDunk.MES.Client.ViewModels.Facility;
using SlamDunk.MES.IAppService.DTOs.Outputs.PlanContext;
using SlamDunk.MES.IAppService.DTOs.Outputs.ResourceContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.MES.Presentation.Models;
using SlamDunk.MES.Presentation.Models.NotifyModels;
using SlamDunk.MES.ReportView.Models;
using SlamDunk.ValueObjects.Enums;

namespace SlamDunk.MES.Client.ViewModels.Report
{
    /// <summary>
    /// 工单物料投入统计ViewModel
    /// </summary>
    public class WorkOrderActualInputMaterialsReportViewModel : ScreenBase
    {
        #region # 字段及构造器
        /// <summary>
        /// 作业管理服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IExecutionContract> _iExecutionContract;

        /// <summary>
        /// 资源定义服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IResourceContract> _iResourceContract;

        /// <summary>
        /// 计划管理服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IPlanContract> _planContract;

        /// <summary>
        /// 报表统计服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IReportContract> _iReportContract;

        /// <summary>
        /// 窗口管理器
        /// </summary>
        private readonly IWindowManager _windowManager;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public WorkOrderActualInputMaterialsReportViewModel(ServiceProxy<IExecutionContract> iExecutionContract, ServiceProxy<IResourceContract> iResourceContract, ServiceProxy<IPlanContract> planContract, ServiceProxy<IReportContract> iReportContract, IWindowManager windowManager)
        {
            this._iExecutionContract = iExecutionContract;
            this._iResourceContract = iResourceContract;
            this._planContract = planContract;
            this._iReportContract = iReportContract;
            this._windowManager = windowManager;
        }
        #endregion

        #region 属性

        #region 开始时间 —— DateTime? StartTime
        /// <summary>
        /// 开始时间
        /// </summary>
        [DependencyProperty]
        public DateTime? StartTime { get; set; }
        #endregion

        #region 结束时间 —— DateTime? EndTime
        /// <summary>
        /// 结束时间
        /// </summary>
        [DependencyProperty]
        public DateTime? EndTime { get; set; }
        #endregion

        #region 物料定义
        /// <summary>
        /// 物料定义
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<MaterialInfo> Materials { get; set; }
        #endregion

        #region 已选物料定义
        /// <summary>
        /// 已选物料定义
        /// </summary>
        [DependencyProperty]
        public MaterialInfo SelectedMaterial { get; set; }
        #endregion

        #region 已选工厂模型 —— Node SelectedFacility
        /// <summary>
        /// 已选工厂模型
        /// </summary>
        [DependencyProperty]
        public Node SelectedFacility { get; set; }
        #endregion

        #region 物料投入统计列表
        /// <summary>
        /// 物料投入统计列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<MaterialSummaryNm> MaterialSummaryReports { get; set; }
        #endregion
        #endregion

        #region # 方法

        //Initializations

        #region 初始化 —— override async Task OnInitializeAsync(CancellationToken cancellationToken)
        /// <summary>
        /// 初始化
        /// </summary>
        protected override async Task OnInitializeAsync(CancellationToken cancellationToken)
        {
            PageModel<MaterialInfo> materials = await Task.Run(() => this._iResourceContract.Channel.GetMaterialsByPage(
                  null,//关键字
                  null,//物料来源类型
                  null,//是否按批量管理
                  null,//工厂模型Id
                  true,//是否启用
                  null,//物料类Id
                  1,
                  int.MaxValue));
            Materials = new ObservableCollection<MaterialInfo>(materials.Datas);

            StartTime = DateTime.Now.AddDays(-30);
            EndTime = DateTime.Now;
            await this.ReloadMaterialSummaryReports();
        }
        #endregion

        //Actions
        #region 选择工厂模型 —— async void SelectFacility()
        /// <summary>
        /// 选择工厂模型
        /// </summary>
        public async void SelectFacility()
        {
            this.Busy();

            SelectFacilityViewModel viewModel = ResolveMediator.Resolve<SelectFacilityViewModel>();
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                this.SelectedFacility = viewModel.SelectedFacility;
            }

            this.Idle();
        }
        #endregion

        #region 清空工厂模型 —— async void ClearFacility()
        /// <summary>
        /// 清空工厂模型
        /// </summary>
        public async void ClearFacility()
        {
            this.SelectedFacility = null;
        }
        #endregion

        #region 查看物料投入统计 —— async void LoadMaterialSummaryReport()
        /// <summary>
        /// 查看物料投入统计
        /// </summary>
        public async void LoadMaterialSummaryReport()
        {
            await this.ReloadMaterialSummaryReports();
        }
        #endregion

        #region 查看明细
        /// <summary>
        /// 查看明细
        /// </summary>
        public async void LookMaterialSummaryReport(MaterialSummaryNm materialSummaryNm)
        {
            this.Busy();
            WorkOrderActualInputMaterialsDetailtReportViewModel viewModel = ResolveMediator.Resolve<WorkOrderActualInputMaterialsDetailtReportViewModel>();
            viewModel.Load(materialSummaryNm);
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            this.Idle();
        }
        #endregion 
        //Private

        #region 加载物料投入统计列表 —— async Task ReloadMaterialSummaryReports()
        /// <summary>
        /// 加载物料投入统计列表
        /// </summary>
        private async Task ReloadMaterialSummaryReports()
        {
            MaterialSummaryReports = new ObservableCollection<MaterialSummaryNm>();
            this.Busy();
            DateTime? startTime = this.StartTime;
            DateTime? endTime = this.EndTime;
            Guid? facilityId = this.SelectedFacility?.Id;
            //查询生成计划
            PageModel<ExecutionPlanInfo> pageModel = await Task.Run(() => this._planContract.Channel.GetExecutionPlansByPage(
                null,//关键字
                null, //产品Id
                null, //工艺Id
                null, //物料清单Id
                null,//生产计划Id
                null,//作业计划状态
                null, //审核状态
                true, //是否已生成工单
                null, //是否已质检
                startTime,//开始时间
                endTime, //结束时间
                facilityId,//工厂模型Id
                1, //页码
                int.MaxValue));
            foreach (var executionPlanInfo in pageModel.Datas)
            {
                //获取作业计划设备使用概要列表
                IEnumerable<MaterialSummaryInfo> materialSummaryList = this._iReportContract.Channel.GetExecutionPlanMaterialUseSummaries(executionPlanInfo.Id, MaterialDirectionType.Input);
                foreach (var materialSummaryInfo in materialSummaryList)
                {
                    //查询集合中是否存在重复员工
                    MaterialSummaryNm materialSummaryReport = MaterialSummaryReports.SingleOrDefault(x => x.MaterialId == materialSummaryInfo.MaterialId && x.MaterialLotId == materialSummaryInfo.MaterialLotId);
                    if (materialSummaryReport == null)
                    {
                        MaterialSummaryNm materialSummaryNm = new MaterialSummaryNm();
                        materialSummaryNm.MaterialId = materialSummaryInfo.MaterialId;
                        materialSummaryNm.MaterialNo = materialSummaryInfo.MaterialNo;
                        materialSummaryNm.MaterialName = materialSummaryInfo.MaterialName;
                        materialSummaryNm.MaterialLotId = materialSummaryInfo.MaterialLotId;
                        materialSummaryNm.SupplierId = materialSummaryInfo.SupplierId;
                        materialSummaryNm.SupplierNo = materialSummaryInfo.SupplierNo;
                        materialSummaryNm.SupplierName = materialSummaryInfo.SupplierName;
                        materialSummaryNm.ProductionBatchNo = materialSummaryInfo.ProductionBatchNo;
                        materialSummaryNm.ProducedDate = materialSummaryInfo.ProducedDate;
                        materialSummaryNm.GuaranteePeriod = materialSummaryInfo.GuaranteePeriod;
                        materialSummaryNm.ExpiredDate = materialSummaryInfo.ExpiredDate;
                        materialSummaryNm.ReceptionDate = materialSummaryInfo.ReceptionDate;
                        materialSummaryNm.Specification = materialSummaryInfo.Specification;
                        materialSummaryNm.MaterialSourceType = materialSummaryInfo.MaterialSourceType;
                        materialSummaryNm.Quantity = materialSummaryInfo.Quantity;
                        materialSummaryNm.QuantityUnitNo = materialSummaryInfo.QuantityUnitNo;
                        materialSummaryNm.PlanStartTime = StartTime;
                        materialSummaryNm.PlanEndTime = EndTime;
                        materialSummaryNm.ExecutionPlanId = executionPlanInfo.Id;

                        ObservableCollection<MaterialSummaryDetailNm> materialSummaryDetailtReportInfos = new ObservableCollection<MaterialSummaryDetailNm>();

                        MaterialSummaryDetailNm materialSummaryDetailNm = new MaterialSummaryDetailNm();
                        materialSummaryDetailNm.MaterialNo = materialSummaryInfo.MaterialNo;
                        materialSummaryDetailNm.MaterialName = materialSummaryInfo.MaterialName;
                        materialSummaryDetailNm.SupplierNo = materialSummaryInfo.SupplierNo;
                        materialSummaryDetailNm.SupplierName = materialSummaryInfo.SupplierName;
                        materialSummaryDetailNm.MaterialProductionBatchNo = materialSummaryInfo.ProductionBatchNo;
                        materialSummaryDetailNm.ProducedDate = materialSummaryInfo.ProducedDate;
                        materialSummaryDetailNm.GuaranteePeriodTicks = materialSummaryInfo.GuaranteePeriodTicks;
                        materialSummaryDetailNm.ExpiredDate = materialSummaryInfo.ExpiredDate;
                        materialSummaryDetailNm.ReceptionDate = materialSummaryInfo.ReceptionDate;
                        materialSummaryDetailNm.Specification = materialSummaryInfo.Specification;
                        materialSummaryDetailNm.Quantity = materialSummaryInfo.Quantity;
                        materialSummaryDetailNm.QuantityUnitNo = materialSummaryInfo.QuantityUnitNo;
                        materialSummaryDetailNm.ExecutionPlanNo = executionPlanInfo.Number;
                        materialSummaryDetailNm.ExecutionPlanName = executionPlanInfo.Name;
                        materialSummaryDetailNm.ProductionBatchNo = executionPlanInfo.ProductionBatchNo;
                        materialSummaryDetailtReportInfos.Add(materialSummaryDetailNm);
                        materialSummaryNm.ExecutionPlanList = materialSummaryDetailtReportInfos;

                        MaterialSummaryReports.Add(materialSummaryNm);
                    }
                    else
                    {
                        int index = MaterialSummaryReports.IndexOf(materialSummaryReport);
                        MaterialSummaryReports.Remove(materialSummaryReport);
                        materialSummaryReport.Quantity += materialSummaryReport.Quantity;
                        MaterialSummaryDetailNm materialSummaryDetailNm = new MaterialSummaryDetailNm();
                        materialSummaryDetailNm.MaterialNo = materialSummaryInfo.MaterialNo;
                        materialSummaryDetailNm.MaterialName = materialSummaryInfo.MaterialName;
                        materialSummaryDetailNm.SupplierNo = materialSummaryInfo.SupplierNo;
                        materialSummaryDetailNm.SupplierName = materialSummaryInfo.SupplierName;
                        materialSummaryDetailNm.MaterialProductionBatchNo = materialSummaryInfo.ProductionBatchNo;
                        materialSummaryDetailNm.ProducedDate = materialSummaryInfo.ProducedDate;
                        materialSummaryDetailNm.GuaranteePeriodTicks = materialSummaryInfo.GuaranteePeriodTicks;
                        materialSummaryDetailNm.ExpiredDate = materialSummaryInfo.ExpiredDate;
                        materialSummaryDetailNm.ReceptionDate = materialSummaryInfo.ReceptionDate;
                        materialSummaryDetailNm.Specification = materialSummaryInfo.Specification;
                        materialSummaryDetailNm.Quantity = materialSummaryInfo.Quantity;
                        materialSummaryDetailNm.QuantityUnitNo = materialSummaryInfo.QuantityUnitNo;
                        materialSummaryDetailNm.ExecutionPlanNo = executionPlanInfo.Number;
                        materialSummaryDetailNm.ExecutionPlanName = executionPlanInfo.Name;
                        materialSummaryDetailNm.ProductionBatchNo = executionPlanInfo.ProductionBatchNo;
                        materialSummaryReport.ExecutionPlanList.Add(materialSummaryDetailNm);
                        this.MaterialSummaryReports.Insert(index, materialSummaryReport);
                    }
                }
            }
            if (SelectedMaterial != null)
            {
                MaterialSummaryReports = new ObservableCollection<MaterialSummaryNm>(MaterialSummaryReports.Where(x => x.MaterialId == SelectedMaterial.Id));
            }
            this.Idle();
        }
        #endregion
        #endregion

    }
}
